package com.github.beihaifeiwu.myspring.autoconfigure;

import com.github.beihaifeiwu.myspring.command.BuiltinCommands;
import com.github.beihaifeiwu.myspring.command.CommandAnnotationBeanPostProcessor;
import com.github.beihaifeiwu.myspring.command.CommandDispatcher;
import com.github.beihaifeiwu.myspring.command.CommandProperties;
import com.github.beihaifeiwu.myspring.core.AbstractBeanPostProcessorsRegistrar;
import com.github.beihaifeiwu.myspring.core.MySpringConstants;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * Created by liupin on 2017/2/6.
 */
@Configuration
@ConditionalOnProperty(prefix = MySpringConstants.COMMAND_PROP_PREFIX, name = "enabled")
@Import(CommandAutoConfiguration.CommandAnnotationBeanPostProcessorRegistrar.class)
@EnableConfigurationProperties(CommandProperties.class)
public class CommandAutoConfiguration {

    @Bean
    public BuiltinCommands builtinCommands() {
        return new BuiltinCommands();
    }

    @Bean
    public CommandDispatcher commandDispatcher(ThreadPoolTaskExecutor executor) {
        return new CommandDispatcher(executor);
    }

    static class CommandAnnotationBeanPostProcessorRegistrar
            extends AbstractBeanPostProcessorsRegistrar {

        @Override
        protected void doRegister(AnnotationMetadata annotationMetadata,
                                  BeanDefinitionRegistry registry) {
            Class<CommandAnnotationBeanPostProcessor> beanClass =
                    CommandAnnotationBeanPostProcessor.class;
            if (isRegistered(beanClass)) {
                return;
            }
            RootBeanDefinition definition = new RootBeanDefinition(beanClass);
            definition.setSynthetic(true);
            registry.registerBeanDefinition("commandAnnotationBeanPostProcessor", definition);
        }

    }

}
